﻿using System;

namespace TestByWire.Tutorial.Domain
{
	public class LogicLayer
	{
		private readonly IDataLayer _dataLayer;
		private readonly ILog _log;

#pragma warning disable 649
		private int _theValue;
#pragma warning restore 649

		public LogicLayer(IDataLayer dataLayer, ILog log)
		{
			_dataLayer = dataLayer;
			_log = log;
		}

		public string Execute()
		{
			_log.Write("Executing...");

			return _dataLayer.Execute();
		}

		public int GetValue()
		{
			return _theValue;
		}
	}

	public class LogicLayerEx
	{
		private readonly IDataLayer _dataLayer;
		private readonly IDataLayer _dataLayerEx;
		private readonly ILog _log;

		public LogicLayerEx(IDataLayer dataLayer, ILog log)
		{
			_dataLayer = dataLayer;
			_log = log;
		}

		public string Execute()
		{
			_log.Write("Executing...");

			return _dataLayer.Execute();
		}

		public string ExecuteEx()
		{
			_log.Write("Executing Ex...");

			return _dataLayerEx.Execute();
		}

		public string[] ArrayExecute()
		{
			return _dataLayerEx.ArrayExecute();
		}
	}

	public interface IDataLayer
	{
		string Execute();
		string[] ArrayExecute();
	}

	public sealed class DataLayer : IDataLayer
	{
		public const string UniqueString = "934823489573489";

		public string Execute()
		{
			return UniqueString;
		}

		public string[] ArrayExecute()
		{
			return new[] { "XXX", "YYY", "ZZZ" };
		}
	}

	public interface ILog
	{
		void Write(string message);
	}

	public class RealLog : ILog
	{
		[ThreadStatic]
		public static string WrittenMessage;

		public void Write(string message)
		{
			WrittenMessage = message;
		}
	}

	public class OtherDataLayer : IDataLayer
	{
		public const string UniqueString = "FL,VMDLKGFE A";

		public string Execute()
		{
			return UniqueString;
		}

		public string[] ArrayExecute()
		{
			return null;
		}
	}
}
